package com.d3works.apps.base.service;

import com.d3works.apps.base.db.Period;
import com.d3works.apps.base.db.repo.PeriodRepository;
import com.d3works.apps.base.exceptions.BaseExceptionMessage;
import com.d3works.apps.message.service.MailMessageService;
import com.d3works.auth.AuthUtils;
import com.d3works.exception.D3worksException;
import com.d3works.exception.service.TraceBackService;
import com.d3works.i18n.I18n;
import com.d3works.inject.Beans;
import com.google.inject.persist.Transactional;
import com.google.inject.servlet.RequestScoper;
import com.google.inject.servlet.ServletScopes;
import java.util.Collections;
import java.util.concurrent.Callable;

public class ClosePeriodCallableService implements Callable<Period> {

  private Period period;

  public void setPeriod(Period period) {
    this.period = period;
  }

  @Override
  public Period call() throws D3worksException {
    final RequestScoper scope = ServletScopes.scopeRequest(Collections.emptyMap());
    try (RequestScoper.CloseableScope ignored = scope.open()) {
      period = Beans.get(PeriodRepository.class).find(period.getId());
      closePeriodAndSendMessage();
      return period;
    } catch (Exception e) {
      onRunnerException(e);
      throw e;
    }
  }

  protected void closePeriodAndSendMessage() throws D3worksException {
    Beans.get(PeriodService.class).close(period);
    Beans.get(MailMessageService.class)
        .sendNotification(
            AuthUtils.getUser(),
            String.format(I18n.get(BaseExceptionMessage.PERIOD_CLOSING_MESSAGE), period.getName()),
            String.format(I18n.get(BaseExceptionMessage.PERIOD_CLOSING_MESSAGE), period.getName()),
            period.getId(),
            period.getClass());
  }

  @Transactional
  protected void onRunnerException(Exception e) {
    TraceBackService.trace(e);
    Beans.get(MailMessageService.class)
        .sendNotification(
            AuthUtils.getUser(),
            String.format(
                I18n.get(BaseExceptionMessage.PERIOD_CLOSING_EXCEPTION_MESSAGE), period.getName()),
            e.getMessage(),
            period.getId(),
            period.getClass());
  }
}
